local _M = { _VERSION = "1.0.0" }

local browser = require('resty.uaparse.browser')
local osr = require('resty.uaparse.os')
local crawler = require('resty.uaparse.crawler')
local ngx_re_match = ngx.re.match

local function try_crawler(useragent, result)
  if crawler.challenge_google(useragent, result) then
    return true
  end

  if crawler.challenge_crawlers(useragent, result) then
    return true
  end

  return false
end

local function try_browser(useragent, result)
  if browser.challenge_MSIE(useragent, result) then
    return true
  end

  if browser.challenge_vivaldi(useragent, result) then
    return true
  end

  if browser.challenge_yandexbrowser(useragent, result) then
    return true
  end

  if browser.challenge_samsung(useragent, result) then
    return true
  end

  if browser.challenge_safari_chrome(useragent, result) then
    return true
  end

  if browser.challenge_firefox(useragent, result) then
    return true
  end

  if browser.challenge_opera(useragent, result) then
    return true
  end

  if browser.challenge_webview(useragent, result) then
    return true
  end

  return false
end

local function try_os(useragent, result)
  if osr.challenge_windows(useragent, result) then
    return true
  end

  -- OSX PC and iOS devices (strict check)
  if osr.challenge_osx(useragent, result) then
    return true
  end

  -- Linux PC and Android
  if osr.challenge_linux(useragent, result) then
    return true
  end

  -- all useragents matches /(iPhone|iPad|iPod|Android|BlackBerry)/
  if osr.challenge_smart_phone(useragent, result) then
    return true
  end

  -- mobile phones like KDDI-.*
  if osr.challenge_mobile_phone(useragent, result) then
    return true
  end

  -- Nintendo DSi/Wii with Opera
  if osr.challenge_appliance(useragent, result) then
    return true
  end

  if osr.challenge_misc(useragent, result) then
    return true
  end

  return false
end

local function try_sdk(useragent, result)
  local match, err = ngx_re_match(useragent, [[^SensorsAnalytics ([a-zA-Z\d]+) SDK\s?([.0-9]+)?]], "o")
  if match then
      result['os'] = match[1]
      result['browser'] = 'SensorsAnalyticsSDK'
      if match[2] ~= false then
        result['browser_version'] = match[2]
      end
      return true
  end
  return false
end


local function exec_parse(useragent)
  local result = {}

  if string.len(useragent) < 1 or useragent == '-' then
    return result;
  end

  if try_crawler(useragent, result) then
    return result;
  end
  
  if try_browser(useragent, result) then
    if try_os(useragent, result) then
      return result;
    else
      return result;
    end
  end
  if try_sdk(useragent, result) then
    return result;
  end
  -- browser unknown, check os only
  if try_os(useragent, result) then
    return result;
  end

  return result;
end

function _M.parse(useragent)
  useragent = useragent or ''
  return exec_parse(useragent)
end

return _M